iT邦幫忙

2022 iThome 鐵人賽

DAY 9
1

繼昨天講完type跟interface以後,相信大家都對這些型別有多一點點了解。
今天我們來看看Interface、type與物件的更多應用!
(有些時候你在interface或type當中看到的用法,或許可以交互拿來使用看看,像等等要提到的選擇性屬性,或唯讀屬性,是在兩者都能用的)

選擇性的屬性

在JavaScript當中,我們有很多時間是在操作物件,或者是將物件放入函式中進行操作。在操作物件時,若我們只能很僵化的將type或interface固定成特定屬性的組合,未免有些難用。
這時,我們可以使用"?",將它後綴於選擇性的屬性名後:

interface FriedRice {
    name: string
    price: number
    ingredients?: string[]
}

//沒有ingredients也不會報錯
const dish: FriedRice = {
    name:"Yanzhou fried rice",
    price:120,
}

但是,即便我們在interface當中設定某些屬性為選擇性的,我們仍然能在JavaScript當中去取用那個屬性,不過那個屬性如果不存在,他就會是undefined。所以,這裡更理想的做法是:

//為可能不存在的值提供預設值,這用法滿常見的
function fry({ name, price, ingredients = ["egg"] }: FriedRice) {
    console.log(`Dish is ${name} and it's $${price} dollars, it need ${ingredients} to make.`)
}

上面這個範例有個有趣的點,官方文件有特別寫出來,我們不能在被解構的語法中,為屬性增加型別註解

function fry({name: Rice, price: Price}){
    console.log(name) 
    //Cannot find name 'name' Did you mean 'Rice'?
}

(這邊先不管RicePrice到底是什麼型別別名)
因為解構當中,如果屬性後出現冒號":",意思反而是:「請將name傳進來到當前的scope,並將其重新命名為Rice」,所以無法使用型別註解。

唯讀屬性

如果我們很確定一個屬性在物件當中,只能是唯讀而不能/不該被改變的,我們就能在interface的屬性名前加上readonly

interface Person {
    readonly name: string
    age: number
}

const John: Person = {
    name: "John",
    age: 18
}

// Cannot assign to 'name' because it is a read-only property.
John.name = "Allen"

但也不代表說他完全是不可變的,這點就跟在JavaScript當中,透過const去宣告一個原始值跟物件的差別一樣,原始值無法被改變,但物件裡面的屬性/值可以。有這點概念,應該不會被衝康。

小結:今天先簡單講這兩個特性就好,不難且好記。
這邊需要提醒一下讀者,你不用到“完全搞懂”TypeScript才能開始使用TypeScript,從你最近開發的功能開始加上TypeScript,一定會越來越熟練的。


上一篇
第八天!Type Alias & Interface 型別別名與介面
下一篇
第十天!來個回顧吧!
系列文
你也對開始使用typescript感到無力嗎?我也是 - 30天初探typescript30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言